package com.ly.cloud.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ly.cloud.dto.CourseBaseDto;
import com.ly.cloud.dto.CourseBaseXmDto;
import com.ly.cloud.dto.CourseBaseXsDto;
import com.ly.cloud.entity.CourseBasePo;
import com.ly.cloud.entity.CourseBaseXmPo;
import com.ly.cloud.entity.CourseBaseXsPo;
import com.ly.cloud.exception.CloudException;
import com.ly.cloud.exception.biz.BusinessException;
import com.ly.cloud.exception.mapper.DBException;
import com.ly.cloud.mapper.CourseBaseMapper;
import com.ly.cloud.mapper.CourseBaseXmMapper;
import com.ly.cloud.mapper.CourseBaseXsMapper;
import com.ly.cloud.service.CourseManageService;
import com.ly.cloud.utils.BeanCopyUtils;
import com.ly.cloud.vo.CourseBaseVo;
import com.ly.cloud.vo.CourseBaseXmVo;
import com.ly.cloud.vo.CourseBaseXsVo;

/**
 * 课程维护Impl
 * @author caihuihai
 * @date 2018年12月18日 下午8:23:05
 */
@Service
public class CourseManageServiceImpl implements CourseManageService {
	
	@Autowired
	private CourseBaseMapper baseMapper;  //课程基本信息Mapper
	@Autowired
	private CourseBaseXsMapper baseXsMapper;  //课程的学时Mapper
	@Autowired
	private CourseBaseXmMapper baseXmMapper;  //课程的项目Mapper
	
	

	/**
	 * 分页查询课程库基本信息列表
	 */
	@Override
	public Page<CourseBaseVo> selectPage(Page<CourseBaseVo> page,CourseBaseDto dto) {
		try {
			return page.setRecords(baseMapper.selectPage(page,dto));
		} catch (Exception e) {
			throw new CloudException("查询异常，请重试!", e);
		}
	}

	/**
	 * 提交课程基本信息（新增、修改）
	 */
	@Transactional
	@Override
	public boolean submitKc(CourseBaseDto dto, String loginUserName) {
		try {
			if(StringUtils.isBlank(dto.getType())) {
				throw new BusinessException();
			}
			CourseBasePo po = new CourseBasePo();
			BeanUtils.copyProperties(dto, po);
			if(dto.getType().equals("add")) {  //新增
				String kcbh = genKcbh(po);  //生成课程编号
				po.setKch(kcbh);
				po.setCjr(loginUserName);
				po.setCjsj(new Date());
				po.setSfyx("1");  //是否有效，新增时默认有效
				baseMapper.insert(po);
			} else {  //修改
				po.setXgr(loginUserName);
				po.setXgsj(new Date());
				EntityWrapper<CourseBasePo> ew = new EntityWrapper<>();
				ew.where("kch={0}", po.getKch());
				baseMapper.update(po, ew);
			}
			//保存课程库的学时信息，先删除旧数据再保存
			saveKcxs(po.getKch(),dto.getXsList());
			//保存课程库的项目信息，先删除旧数据再保存
			saveKcxm(po.getKch(),dto.getXmList());
			return true;
		} catch (BusinessException e) {
			throw new BusinessException("请传type操作类型值", e);
		} catch (Exception e) {
			throw new DBException("操作异常，请重试!", e);
		}
	}

	/**
	 * 保存课程库的项目信息，先删除旧数据再保存
	 * @param kch
	 * @param xmList 项目信息list
	 */
	private void saveKcxm(String kch, List<CourseBaseXmDto> xmList) {
		try {
			EntityWrapper<CourseBaseXmPo> ew = new EntityWrapper<>();
			ew.where("kch={0}", kch);
			baseXmMapper.delete(ew);
			if(xmList != null) {
				for (CourseBaseXmDto xmDto : xmList) {
					CourseBaseXmPo po = new CourseBaseXmPo();
					BeanUtils.copyProperties(xmDto, po);
					po.setKch(kch);
					baseXmMapper.insert(po);
				}
			}
		} catch (Exception e) {
			throw new DBException("保存课程库的项目信息失败，请联系管理员", e);
		}
		
	}

	/**
	 * 保存课程库的学时信息，先删除旧数据再保存
	 * @param kch
	 * @param xsList 学时信息list
	 */
	private void saveKcxs(String kch, List<CourseBaseXsDto> xsList) {
		try {
			EntityWrapper<CourseBaseXsPo> ew = new EntityWrapper<>();
			ew.where("kch={0}", kch);
			baseXsMapper.delete(ew);
			if(xsList != null) {
				for (CourseBaseXsDto xsDto : xsList) {
					CourseBaseXsPo po = new CourseBaseXsPo();
					BeanUtils.copyProperties(xsDto, po);
					po.setKch(kch);
					baseXsMapper.insert(po);
				}
			}
		} catch (Exception e) {
			throw new DBException("保存课程库的学时信息失败，请联系管理员", e);
		}
	}

	/**
	 * 新增时先生成课程编号
	 * 暂定生成规则，后续动态接编码规则
	 * 生成规则：开课单位后两位 + 课程属性后一位 + 课程性质后一位 + 课程类别后一位 + 流水号三位
	 * @param po
	 * @return
	 */
	private String genKcbh(CourseBasePo po) {
		try {
			String kcbh = ""; //课程编号
			String lsh = "001";  //流水号
			//先查询是否存在课程编号，如果存在课程编号的话则查找后三位作为流水号，下一个课程编号+1开始
			EntityWrapper<CourseBasePo> ew = new EntityWrapper<>();
			ew.where("kkxy={0} and kcsx={1} and kcxz={2} and kclb={3}", po.getKkxy(),po.getKcsx(),po.getKcxz(),po.getKclb());
			ew.orderBy("kch", false);  //课程编号降序排
			List<CourseBasePo> list = baseMapper.selectList(ew);
			if(list.size() > 0) {
				String oldKchStr = list.get(0).getKch();
				int oldKchLsh = Integer.parseInt(oldKchStr.substring(oldKchStr.length()-3, oldKchStr.length())); //旧的流水号
				String newKchLsh = String.valueOf(oldKchLsh + 1);  //新的流水号
				lsh = subCodeStr(newKchLsh,3); //流水号
			} 
			String kkxy = subCodeStr(po.getKkxy(),2); //开课单位后两位
			String kcsx = subCodeStr(po.getKcsx(),1); //课程属性后一位
			String kcxz = subCodeStr(po.getKcxz(),1); //课程性质后一位
			String kclb = subCodeStr(po.getKclb(),1); //课程类别后一位
			kcbh = kkxy + kcsx + kcxz + kclb + lsh;  //开课单位后两位 + 课程属性后一位 + 课程性质后一位 + 课程类别后一位 + 流水号三位
			return kcbh;
		} catch (Exception e) {
			throw new CloudException("生成课程编码有问题，请联系管理员", e);
		}
	}
	
	/**
	 * 截取字符串后num位，不够num位则在前面补0
	 * @param code 字符串
	 * @param num 位数
	 * @return
	 */
	private String subCodeStr(String code,int num) {
		try {
			String value = "";
			if(code.length() < num) {   //字符串小于要截取的位数，则直接在前面补位
				value = code;
				for(int i=0;i<num-code.length();i++) {
					value = "0"+value;
				}
			} else {  //字符串大于要截取的位数，则先截取再补位
				value = code.substring(code.length()-num, code.length());
				if(value.length() != num) {
					for(int i=0;i<num-value.length();i++) {
						value = "0"+value;
					}
				}
			}
			return value;
		} catch (Exception e) {
			throw new CloudException("截取字符串有问题，请联系管理员", e);
		}
	}

	/**
	 * 删除课程的项目信息
	 */
	@Override
	public boolean deleteKcxm(String kch, String xmbh) {
		try {
			EntityWrapper<CourseBaseXmPo> ew = new EntityWrapper<>();
			ew.where("kch={0} and xmbh={1}", kch,xmbh);
			baseXmMapper.delete(ew);
			return true;
		} catch (Exception e) {
			throw new DBException("删除课程项目信息失败", e);
		}
	}

	/**
	 * 批量删除课程
	 * 则把相应的课程学时和课程项目也删除
	 */
	@Transactional
	@Override
	public boolean batchDelKc(List<String> kchs) {
		try {
			for (String kch : kchs) {
				//1、删除课程
				EntityWrapper<CourseBasePo> ew = new EntityWrapper<>();
				ew.where("kch={0}", kch);
				baseMapper.delete(ew);
				//2、删除课程学时
				EntityWrapper<CourseBaseXsPo> xsEw = new EntityWrapper<>();
				xsEw.where("kch={0}", kch);
				baseXsMapper.delete(xsEw);
				//3、删除课程项目
				EntityWrapper<CourseBaseXmPo> xmEw = new EntityWrapper<>();
				xmEw.where("kch={0}", kch);
				baseXmMapper.delete(xmEw);
			}
			return true;
		} catch (Exception e) {
			throw new DBException("删除课程失败", e);
		}
	}

	/**
	 * 根据课程编号查询课程信息（包括学时、项目）
	 */
	@Override
	public CourseBaseVo findKcxxByKch(String kch) {
		try {
			//1、查询课程库基本信息
			CourseBaseVo vo = new CourseBaseVo();
			CourseBasePo po = new CourseBasePo();
			po.setKch(kch);
			CourseBasePo selPo = baseMapper.selectOne(po);
			BeanUtils.copyProperties(selPo, vo);
			//2、查看学时信息列表
			EntityWrapper<CourseBaseXsPo> xsEw = new EntityWrapper<>();
			xsEw.where("kch={0}", kch);
			List<CourseBaseXsPo> xsPoList = baseXsMapper.selectList(xsEw);
			vo.setXsList(BeanCopyUtils.copyListProperties(xsPoList, CourseBaseXsVo.class));
			//3、查询项目信息列表
			EntityWrapper<CourseBaseXmPo> xmEw = new EntityWrapper<>();
			xmEw.where("kch={0}", kch);
			List<CourseBaseXmPo> xmPoList = baseXmMapper.selectList(xmEw);
			vo.setXmList(BeanCopyUtils.copyListProperties(xmPoList, CourseBaseXmVo.class));
			return vo;
		} catch (Exception e) {
			throw new CloudException("查询课程信息失败", e);
		}
	}

}
